package org.jvm.instruction.references;

import org.jvm.instruction.base.Index16Instruction;
import org.jvm.rtda.Object;
import org.jvm.rtda.heap.Klass;
import org.jvm.rtda.heap.symref.ClassRef;
import org.jvm.rtda.thread.Frame;

/**
 * 判断某实例是否可以强制转换为某类型
 * 如果无法转换直接抛异常
 *
 * @author 海燕
 * @date 2023/2/6
 */
public class CHECK_CAST extends Index16Instruction {

    /**
     * 操作数作为索引指向类常量池中类引用符号
     *
     * @param frame
     */
    @Override
    public void execute(Frame frame) {
        //check_cast指令不影响操作数栈
        Object object = frame.getOperandStack().popRef();
        frame.getOperandStack().pushRef(object);
        //null可以转换为任何类型，不抛异常
        if (object == null) {
            return;
        }
        ClassRef classRef = (ClassRef) frame.getMethod().getKlass().getConstantPool().getConstant(this.index);
        Klass superClass = classRef.resolvedClass(frame.getThread());
        if (!object.isInstanceOf(superClass)) {
            throw new RuntimeException("java.lang.ClassCastException");
        }
    }
}
